-- 
-- Please see the readme.txt file included with this distribution for 
-- attribution and copyright information.
--

function onInit()
	-- Find root node to get version
	local rootnode = DB.findNode(".");
	if rootnode then
		local major, minor = rootnode.getRulesetVersion();
		
		-- If we need a conversion, then go for it.
		if major < 15 then
			convertCharacterPowerAbilities(rootnode);
		end
		if major < 16 then
			convertEffects(rootnode);
		end
		if major < 17 then
			convertCTAtkField(rootnode);
		end
		if major < 18 then
			convertSkillTrackerResults(rootnode);
		end
		if major < 19 then
			releaseInvalidOwners(rootnode);
		end

		-- Make sure we update to the latest version to avoid any future conversions
		rootnode.updateVersion();
	end
end

function releaseInvalidOwners(nodeRoot)
	local nodeCT = nodeRoot.getChild("combattracker");
	if nodeCT then
		for keyHolder, sHolder in pairs(nodeCT.getHolders()) do
			nodeCT.removeHolder(sHolder);
		end
	end

	local nodeOptions = nodeRoot.getChild("options");
	if nodeOptions then
		for keyHolder, sHolder in pairs(nodeOptions.getHolders()) do
			nodeOptions.removeHolder(sHolder);
		end
	end
end

function convertSkillTrackerResults(nodeRoot)
	local nodeSkills = nodeRoot.getChild("skillchallenge.skills");
	if nodeSkills then
		for keySkill, nodeSkill in pairs(nodeSkills.getChildren()) do
			local nodeRolls = nodeSkill.getChild("rolls");
			if nodeRolls then
				for keyRoll, nodeRoll in pairs(nodeRolls.getChildren()) do
					local nSuccess = NodeManager.get(nodeRoll, "success", 0);
					if nSuccess == 0 then
						NodeManager.set(nodeRoll, "result", "string", "success");
					else
						NodeManager.set(nodeRoll, "result", "string", "failure");
					end
				end
			end
		end
	end
end

function convertCTAtkField(nodeRoot)
	local nodeCT = nodeRoot.getChild("combattracker");
	if nodeCT then
		for keyCTEntry, nodeCTEntry in pairs(nodeCT.getChildren()) do
			local sAttack = NodeManager.get(nodeCTEntry, "atk", "");
			local aAttacks = StringManager.split(sAttack, ";\r");
			if #aAttacks > 0 then
				local nodeAttacks = NodeManager.createChild(nodeCTEntry, "attacks");
				if nodeAttacks then
					for k, v in pairs(aAttacks) do
						local nodeAttack = NodeManager.createChild(nodeAttacks);
						NodeManager.set(nodeAttack, "value", "string", v);
					end
				end
			end
		end
	end
end

function migrateEffect(effect_node)
	local effect_label = NodeManager.get(effect_node, "label", "");

	local new_effect_list = {};
	local eff_comp_list = EffectsManager.parseEffect(effect_label);
	for eff_comp_key, eff_comp_item in pairs(eff_comp_list) do
		if eff_comp_item.type == "DMG" then
			eff_comp_item.type = "DMGO";
		elseif eff_comp_item.type == "ATKA" then
			eff_comp_item.type = "ATK";
		elseif eff_comp_item.type == "ATKM" then
			eff_comp_item.type = "ATK";
			table.insert(eff_comp_item.remainder, "melee");
		elseif eff_comp_item.type == "ATKR" then
			eff_comp_item.type = "ATK";
			table.insert(eff_comp_item.remainder, "ranged");
		elseif eff_comp_item.type == "DMGA" then
			eff_comp_item.type = "DMG";
		elseif eff_comp_item.type == "DMGM" then
			eff_comp_item.type = "DMG";
			table.insert(eff_comp_item.remainder, "melee");
		elseif eff_comp_item.type == "DMGR" then
			eff_comp_item.type = "DMG";
			table.insert(eff_comp_item.remainder, "ranged");
		end

		local new_comp_entry_list = eff_comp_item.remainder;
		if (#(eff_comp_item.dice) > 0) or (eff_comp_item.mod ~= 0) then
			table.insert(new_comp_entry_list, 1, StringManager.convertDiceToString(eff_comp_item.dice, eff_comp_item.mod));
		end
		if eff_comp_item.type ~= "" then
			table.insert(new_comp_entry_list, 1, eff_comp_item.type .. ":");
		end
		table.insert(new_effect_list, table.concat(new_comp_entry_list, " "));
	end

	NodeManager.set(effect_node, "label", "string", table.concat(new_effect_list, "; "));
end

function convertEffects(rootnode)
	local ct_rootnode = rootnode.getChild("combattracker");
	if ct_rootnode then
		for entry_key, entry_node in pairs(ct_rootnode.getChildren()) do
			local effects_node = entry_node.getChild("effects");
			if effects_node then
				for effect_key, effect_node in pairs(effects_node.getChildren()) do
					migrateEffect(effect_node);
				end
			end
		end
	end

	local campaigneffects_node = rootnode.getChild("effects");
	if campaigneffects_node then
		for effect_key, effect_node in pairs(campaigneffects_node.getChildren()) do
			migrateEffect(effect_node);
		end
	end

	local character_rootnode = rootnode.getChild("charsheet");
	if character_rootnode then
		for kchar, charnode in pairs(character_rootnode.getChildren()) do
			local powers_node = charnode.getChild("powers");
			if powers_node then
				for kpowertype, powertypenode in pairs(powers_node.getChildren()) do
					local powerlistnode = powertypenode.getChild("power");
					if powerlistnode then
						for kpower, poweritemnode in pairs(powerlistnode.getChildren()) do
							local powerabilitiesnode = poweritemnode.getChild("abilities");
							if powerabilitiesnode then
								for kability, abilitynode in pairs(powerabilitiesnode.getChildren()) do
									if NodeManager.get(abilitynode, "type", "") == "effect" then
										migrateEffect(abilitynode);
									end
								end
							end
						end
					end
				end
			end
		end
	end
end

function convertCharacterPowerAbilities(rootnode)
	local character_rootnode = rootnode.getChild("charsheet");
	if character_rootnode then
		for kchar, charnode in pairs(character_rootnode.getChildren()) do
			local powers_node = charnode.getChild("powers");
			if powers_node then
				for kpowertype, powertypenode in pairs(powers_node.getChildren()) do
					local powerlistnode = powertypenode.getChild("power");
					if powerlistnode then
						for kpower, poweritemnode in pairs(powerlistnode.getChildren()) do
							local powerabilitylistnode = poweritemnode.createChild("abilities");
							if powerabilitylistnode then
								local ability_order = 1;

								local powerattacklistnode = poweritemnode.getChild("attacks");
								if powerattacklistnode then
									for kattack, powerattackitemnode in pairs(powerattacklistnode.getChildren()) do
										local copyflag = false;
										if (NodeManager.get(powerattackitemnode, "attackstat", "") ~= "") or
												(NodeManager.get(powerattackitemnode, "attackstatmodifier", 0) ~= 0) or
												(NodeManager.get(powerattackitemnode, "attackdef", "") ~= "") or
												(NodeManager.get(powerattackitemnode, "damageweaponmult", 0) ~= 0) or
												(NodeManager.get(powerattackitemnode, "damagestat", "") ~= "") or
												(NodeManager.get(powerattackitemnode, "damagestat2", "") ~= "") or
												(NodeManager.get(powerattackitemnode, "damagestatmodifier", 0) ~= 0) or
												(NodeManager.get(powerattackitemnode, "damagetype", "") ~= "") then
											copyflag = true;
										else
											local dicenode = powerattackitemnode.getChild("damagebasicdice");
											if dicenode then
												local dice = dicenode.getValue();
												if dice and #dice > 0 then
													copyflag = true;
												end
											end
										end

										if copyflag then
											local powerabilitynode = NodeManager.copy(powerattackitemnode, powerabilitylistnode, true);

											NodeManager.set(powerabilitynode, "order", "number", ability_order);
											ability_order = ability_order + 1;
											NodeManager.set(powerabilitynode, "type", "string", "attack");
										end
									end

									powerattacklistnode.delete();
								end
								local powereffectlistnode = poweritemnode.getChild("effects");
								if powereffectlistnode then
									for kattack, powereffectitemnode in pairs(powereffectlistnode.getChildren()) do
										local copyflag = false;
										if NodeManager.get(powereffectitemnode, "label", "") ~= "" then
											copyflag = true;
										end

										if copyflag then
											local powerabilitynode = NodeManager.copy(powereffectitemnode, powerabilitylistnode, true);

											NodeManager.set(powerabilitynode, "order", "number", ability_order);
											ability_order = ability_order + 1;
											NodeManager.set(powerabilitynode, "type", "string", "effect");
										end
									end

									powereffectlistnode.delete();
								end
							end
						end
					end
				end
			end
		end
	end
end